package containers

import (
	"context"
	"server/internal/common/biz"
	"server/internal/svc"
	"server/internal/types"
	"strconv"
	"strings"

	"github.com/zeromicro/go-zero/core/logx"
)

type ContainerLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// get container detail
func NewContainerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ContainerLogic {
	return &ContainerLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *ContainerLogic) Container(req *types.ContianerReq) (resp *types.ContainerResp, err error) {

	container, err := l.svcCtx.DockerCli.ContainerInspect(l.ctx, req.Id)
	if err != nil {
		l.Logger.Errorf("get container detail failed: %s", err)
		return nil, biz.ContainerGetError
	}

	return &types.ContainerResp{
		ID:      container.ID,
		Name:    container.Name,
		Image:   container.Config.Image,
		ImageID: container.Image[7:],
		Command: strings.Join(container.Config.Cmd, " "),
		Created: container.Created,
		State:   container.State.Status,
		Ports: func() []types.Port {
			ports := container.HostConfig.PortBindings
			p := make([]types.Port, 0, len(ports))
			for key, values := range ports {
				port := key.Int()
				t := key.Proto()
				for _, value := range values {
					publicPort, _ := strconv.ParseUint(value.HostPort, 10, 16)
					p = append(p, types.Port{
						IP:          value.HostIP,
						PrivatePort: uint16(port),
						PublicPort:  uint16(publicPort),
						Type:        t,
					})
				}

			}
			return p
		}(),
		Labels: container.Config.Labels,
		Mounts: func() []types.Mount {
			ms := make([]types.Mount, 0, len(container.Mounts))
			for _, mount := range container.Mounts {
				ms = append(ms, types.Mount{
					Source:      mount.Source,
					Destination: mount.Destination,
					Type:        string(mount.Type),
					Name:        mount.Name,
					Driver:      mount.Driver,
					RW:          mount.RW,
					Propagation: string(mount.Propagation),
				})
			}
			return ms
		}(),
		Detail: container,
	}, nil
}
